package com.ocom.payconfig.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ocom.common.dto.MealMenuBDTO;
import com.ocom.common.entity.payconfig.EntityMealMenu;
import com.ocom.common.entity.payconfig.EntityMealPlan;
import com.ocom.common.enums.DataSourceEnum;
import com.ocom.common.request.payconfig.DishesIdVo;
import com.ocom.common.request.payconfig.RemoveMealPlanRequest;
import com.ocom.common.request.payconfig.mealorder.GetOrderDishesInfoDao;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.payconfig.MealMenuVo;
import com.ocom.mysql.aspect.DataSourceAspect;
import com.ocom.payconfig.dao.IDaoMealMenu;
import com.ocom.payconfig.po.MealMenuListBVO;
import com.ocom.payconfig.service.MealMenuService;
import com.ocom.payconfig.service.MealPlanService;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class MealMenuServiceImpl extends ServiceImpl<IDaoMealMenu, EntityMealMenu> implements MealMenuService {

	@Autowired
	IDaoMealMenu iDaoMealMenu;

	@Autowired
	MealPlanService mealPlanService;

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public List<EntityMealMenu> mealMenuList(Long companyId, EntityMealMenu entityMealMenu) {
		return iDaoMealMenu.mealMenuList(
				entityMealMenu.getComId(),
				entityMealMenu.getMerchId(),
				entityMealMenu.getMealplanId(),
				entityMealMenu.getDays(),
				entityMealMenu.getMealNo()
		);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public Boolean removeMealMenu(Long companyId, RemoveMealPlanRequest request) {
		QueryWrapper<EntityMealMenu> queryWrapper = Wrappers.query();
		//com_id、merch_id、mealplan_id
		queryWrapper.eq("com_id", request.getComId());
//		queryWrapper.eq("merch_id", request.getMerchId());
		queryWrapper.eq("mealplan_id", request.getMealplanId());
		return this.remove(queryWrapper);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public Boolean clearMealMenu(Long companyId, EntityMealMenu entityMealMenu) {
		QueryWrapper<EntityMealMenu> queryWrapper = Wrappers.query();
		//com_id、merch_id、mealplan_id
		queryWrapper.eq("com_id", entityMealMenu.getComId());
		queryWrapper.eq("merch_id", entityMealMenu.getMerchId());
		queryWrapper.eq("mealplan_id", entityMealMenu.getMealplanId());
		if (entityMealMenu.getDays() != null && entityMealMenu.getDays() > 0) {
			queryWrapper.eq("days", entityMealMenu.getDays());
		}
		if (entityMealMenu.getMealNo() != null && entityMealMenu.getMealNo() > 0) {
			queryWrapper.eq("meal_no", entityMealMenu.getMealNo());
		}
		return this.remove(queryWrapper);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public void saveMealMenu(Long companyId, EntityMealMenu entityMealMenu) {
		List<EntityMealPlan> mealPlanList = mealPlanService.mealPlanList(companyId);

		//list转map
		Map<Integer, Integer> pointMap = mealPlanList.stream().collect(Collectors.toMap(e -> e.getMealplanId(),
				e -> e.getPointId(),
				(e1, e2) -> e1));

		QueryWrapper<EntityMealMenu> queryWrapper = Wrappers.query();
		queryWrapper.eq("com_id", entityMealMenu.getComId());
		queryWrapper.eq("merch_id", entityMealMenu.getMerchId());
		queryWrapper.eq("mealplan_id", entityMealMenu.getMealplanId());
		queryWrapper.eq("days", entityMealMenu.getDays());
		queryWrapper.eq("meal_no", entityMealMenu.getMealNo());
		this.remove(queryWrapper);

		if (entityMealMenu.getDishesList() == null || entityMealMenu.getDishesList().size() == 0) {
			return;
		}
		List<EntityMealMenu> batchSave = new ArrayList<>();
		for (DishesIdVo dishesIdVo : entityMealMenu.getDishesList()) {

			if (dishesIdVo.getPrice() == null) {
				dishesIdVo.setPrice(0);
			}
			if (dishesIdVo.getLimitedQuantity() == null) {
				dishesIdVo.setLimitedQuantity(0);
			}

			EntityMealMenu mealMenu = new EntityMealMenu();
			mealMenu.setComId(entityMealMenu.getComId());
			mealMenu.setMerchId(entityMealMenu.getMerchId());
			mealMenu.setMealplanId(entityMealMenu.getMealplanId());
			mealMenu.setDays(entityMealMenu.getDays());
			mealMenu.setMealNo(entityMealMenu.getMealNo());
			if (pointMap.containsKey(entityMealMenu.getMealplanId())) {
				mealMenu.setPointId(pointMap.get(entityMealMenu.getMealplanId()));
			} else {
				mealMenu.setPointId(0);
			}
			mealMenu.setDishesId(dishesIdVo.getDishesId());
			mealMenu.setSort(dishesIdVo.getSort());
			mealMenu.setPriceMode(dishesIdVo.getPriceMode());
			mealMenu.setPrice(dishesIdVo.getPrice());
			mealMenu.setLimitedQuantity(dishesIdVo.getLimitedQuantity());

			batchSave.add(mealMenu);
		}
		this.saveBatch(batchSave);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public void removeMealMenu(Long companyId, EntityMealMenu entityMealMenu) {
		QueryWrapper<EntityMealMenu> queryWrapper = Wrappers.query();
		queryWrapper.eq("com_id", entityMealMenu.getComId());
		queryWrapper.eq("merch_id", entityMealMenu.getMerchId());
		queryWrapper.eq("mealplan_id", entityMealMenu.getMealplanId());
		queryWrapper.eq("days", entityMealMenu.getDays());
		queryWrapper.eq("meal_no", entityMealMenu.getMealNo());
		if (entityMealMenu.getDishesId() != null) {
			queryWrapper.eq("dishes_id", entityMealMenu.getDishesId());
		}
		this.remove(queryWrapper);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public List<MealMenuVo> getMealList(Long companyId, Integer mealplanId, Integer days, Integer mealNo) {
		return iDaoMealMenu.getMealList(companyId,
				mealplanId,
				days,
				mealNo);
	}

	@Override
	@DataSourceAspect(type = DataSourceEnum.PART_DB)
	public List<GetOrderDishesInfoDao> getDishesInfo(Long companyId, Integer mealplanId, Integer days, Integer mealNo) {
		return iDaoMealMenu.getDishesInfo(companyId,
				mealplanId,
				days,
				mealNo);
	}

	@Override
	public Boolean mealMenuService(MealMenuBDTO mealMenuBDTO) {

		RemoveMealPlanRequest request = new RemoveMealPlanRequest();
		request.setComId(mealMenuBDTO.getComId());
		request.setMerchId(mealMenuBDTO.getMerchId());
		request.setMealplanId(mealMenuBDTO.getMealPlanId());
		removeMealMenu(mealMenuBDTO.getComId(), request);


		for (MealMenuBDTO.DishesListDTO item : mealMenuBDTO.getDishesList()) {
			EntityMealMenu mealMenu = new EntityMealMenu();
			mealMenu.setComId(mealMenuBDTO.getComId());
			mealMenu.setMerchId(mealMenuBDTO.getMerchId());
			mealMenu.setMealplanId(mealMenuBDTO.getMealPlanId());
			mealMenu.setPointId(mealMenuBDTO.getPointId());
			mealMenu.setDays(item.getDays());
			mealMenu.setMealNo(item.getMealNo());
			mealMenu.setDishesId(item.getDishesId());
			mealMenu.setDishesList(paseDishesList(mealMenuBDTO, item.getDays(), item.getMealNo()));
			this.saveMealMenu(mealMenuBDTO.getComId(), mealMenu);
		}

		return true;

	}

	private List<DishesIdVo> paseDishesList(MealMenuBDTO mealMenuBDTO, Integer days, Integer mealNo) {
		List<DishesIdVo> dishesIdVos = new ArrayList<>();
		for (MealMenuBDTO.DishesListDTO dto : mealMenuBDTO.getDishesList()) {
			if (dto.getDays() == days && dto.getMealNo() == mealNo){
				DishesIdVo vo = new DishesIdVo();
				vo.setDishesId(dto.getDishesId());
				dishesIdVos.add(vo);
			}
		}
		return  dishesIdVos;
	}


	@Override
	public Result<Map<String, Object>> mealMenuListB(Long companyId, Integer mealPlanId) {
		if (companyId == null || mealPlanId == null || mealPlanId == 0) {
			return null;
		}

		EntityMealPlan mealPlan = mealPlanService.mealPlanInfo(companyId, mealPlanId);

		SimpleDateFormat sdf = new SimpleDateFormat("MM-dd", Locale.SIMPLIFIED_CHINESE);
		Map<String, List<MealListVo>> dayMap = new LinkedHashMap<>();
		List<MealMenuListBVO> mealMenuListBVOS = this.baseMapper.getMealMenuListB(companyId, mealPlan.getMerchId(), mealPlanId);
		if (CollectionUtils.isEmpty(mealMenuListBVOS)) {
			return ResultUtil.success();
		}
		for (MealMenuListBVO item : mealMenuListBVOS) {
			// 把日期往后增加一天,整数  往后推,负数往前移动
			Calendar calendar = new GregorianCalendar();
			calendar.setTime(mealPlan.getStartDate());
			//calendar.add(Calendar.DATE, item.getDays() - 1);
			String dayStr = sdf.format(calendar.getTime());
			int day = calendar.get(Calendar.DAY_OF_WEEK);
			switch (day){
				case 2:
					dayStr = dayStr+"星期一";
					break;
				case 3:
					dayStr = dayStr+"星期二";
					break;
				case 4:
					dayStr = dayStr+"星期三";
					break;
				case 5:
					dayStr = dayStr+"星期四";
					break;
				case 6:
					dayStr = dayStr+"星期五";
					break;
			}


			List<MealListVo> dayListVos = dayMap.get(dayStr);
			if (ObjectUtils.isEmpty(dayListVos)) {
				dayListVos = getMealListVo(item.getDays(), mealMenuListBVOS);
				dayMap.put(dayStr, dayListVos);
			}
		}


		Map<String, List<DayListVo>> result = new HashMap<>();
		List<DayListVo> dataList = new ArrayList();
		for (Map.Entry<String, List<MealListVo>> entry : dayMap.entrySet()) {
			DayListVo vo = new DayListVo();
			vo.setDate(entry.getKey());
			vo.setMealList(entry.getValue());
			dataList.add(vo);
		}
		result.put("dayList", dataList);

		Result<Map<String, Object>> result1 = ResultUtil.success(result);
		return result1;
	}

	private List<MealListVo> getMealListVo(Integer days, List<MealMenuListBVO> mealMenuListBVOS) {

		List<MealMenuListBVO> mealMenuListBVOS1 = mealMenuListBVOS.stream().filter(item -> Objects.equals(item.getDays(), days)).collect(Collectors.toList());
		Map<String, List<DishesListVo>> dishesMap = new HashMap();

		for (MealMenuListBVO item : mealMenuListBVOS1) {
			List<DishesListVo> dishesList = dishesMap.get(item.getMealNo());
			if (ObjectUtils.isEmpty(dishesList)) {
				dishesList = getDishesListVo(item.getMealNo(), mealMenuListBVOS1);
				dishesMap.put(String.valueOf(item.getMealNo()), dishesList);
			}
		}

		List<MealListVo> mealListVoList = new ArrayList<>();

		for (Map.Entry<String, List<DishesListVo>> item : dishesMap.entrySet()) {
			MealListVo vo = new MealListVo();
			vo.setMealNo(item.getKey());
			vo.setDishesList(item.getValue());
			mealListVoList.add(vo);
		}


		return mealListVoList;
	}

	private List<DishesListVo> getDishesListVo(Integer mealNo, List<MealMenuListBVO> mealMenuListBVOS) {
		List<MealMenuListBVO> mealMenuListBVOS1 = mealMenuListBVOS.stream().filter(item -> Objects.equals(item.getMealNo(), mealNo)).collect(Collectors.toList());
		List<DishesListVo> dishesListVo = new ArrayList<>();

		for (MealMenuListBVO item : mealMenuListBVOS1) {
			DishesListVo vo = new DishesListVo();
			vo.setDishesId(item.getDishesId() + "");
			vo.setRemark(item.getRemark());
			vo.setDishesName(item.getDishesName());
			vo.setSort(item.getSort());
			dishesListVo.add(vo);
		}

		return dishesListVo;
	}
}


@Data
class DayListVo {
	private String date;
	private List<MealListVo> mealList;
}

@Data
class MealListVo {
	private String mealNo;
	List<DishesListVo> dishesList;

}

@Data
class DishesListVo {
	String dishesId;
	String dishesName;
	String remark;
	String sort;
}